#include "project_config.h"

#include "vtkActor.h" 
#include "vtkCommand.h" 
#include "vtkConeSource.h" 
#include "vtkInteractorStyleTrackballCamera.h" 
#include "vtkPolyDataMapper.h" 
#include "vtkProperty.h"
#include "vtkRenderWindow.h" 
#include "vtkRenderWindowInteractor.h" 
#include "vtkRenderer.h" 
#include "vtkSphereSource.h"

vtkConeSource *cone;
vtkActor *coneActor;
vtkSphereSource *sphere;
vtkActor *sphereActor;
vtkRenderWindowInteractor *iren;

class vtkSimpleTimerCallback : public vtkCommand {
	public:
		static vtkSimpleTimerCallback *New(){
			vtkSimpleTimerCallback *cb = new vtkSimpleTimerCallback;
			cb->gradientPosition=100;
			cb->gradientStep=-1;
			cb->gradientStepMultiplier=4;
			return cb;
		}

		void setTimerToWatch(int timerId){
			timerToWatch = timerId;
		}

		int getTimerToWatch(){
			return timerToWatch;
		}

		void initColor(vtkProperty *prop){
			prop->GetColor(r,g,b);
		}

		virtual void Execute(vtkObject *caller, unsigned long eventId,void *callData){
			if (vtkCommand::TimerEvent == eventId){
				int timerId = * static_cast<int *>(callData);
				if(timerId != timerToWatch) return;
				
				if(gradientPosition>=100) gradientStep = -1;
				if(gradientPosition<=0) gradientStep = 1;

				double gradientScale = gradientPosition/100.0;
				if(gradientScale<0) gradientScale = 0.0;
				if(gradientScale>1) gradientScale = 1.0;
				sphereActor->GetProperty()->SetColor(gradientScale*r,gradientScale*g,gradientScale*b);

				iren->Render();
				gradientPosition+=(gradientStep*gradientStepMultiplier);
			}
		}
	private:
		int timerToWatch;
		int gradientPosition;
		int gradientStep;
		int gradientStepMultiplier;
		double r,g,b;

};

//int main(int argc, char** argv[])
int old_main(int argc, char** argv[])
{
	cout << "starting..." << endl;

	//Create a cone source object
	cone = vtkConeSource::New();
	cone->SetHeight(3.0);
	cone->SetRadius(1.0);
	cone->SetResolution(10);//200

	//Create a cone mapper object
	vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
	coneMapper->SetInputConnection(cone->GetOutputPort());

	//Associate the cone mapper to an actor object
	coneActor = vtkActor::New();
	coneActor->SetMapper(coneMapper);

	// create sphere geometry
	sphere = vtkSphereSource::New();
	sphere->SetRadius(1.025);
	sphere->SetThetaResolution(10);//50
	sphere->SetPhiResolution(10);//50

	// map to graphics library
	vtkPolyDataMapper *sphereMapper = vtkPolyDataMapper::New();
	sphereMapper->SetInput(sphere->GetOutput());

	// actor coordinates geometry, properties, transformation
	sphereActor = vtkActor::New();
	sphereActor->SetMapper(sphereMapper);
	sphereActor->GetProperty()->SetColor(0,0,1); // sphere color blue
	sphereActor->SetPosition(-1.6,0.0,0.0);

	//Add the actors to the renderer
	vtkRenderer *ren1 = vtkRenderer::New();
	ren1->AddActor(coneActor);
	ren1->AddActor(sphereActor);
	ren1->SetBackground(0.1, 0.2, 0.4);

	//Create a render window
	vtkRenderWindow *renWin = vtkRenderWindow::New();
	renWin->AddRenderer(ren1);
	renWin->SetSize(600,600);

	//Create an interactor and associate it to the render window
	iren = vtkRenderWindowInteractor::New();
	iren->SetRenderWindow(renWin);
	iren->Initialize();

	vtkSimpleTimerCallback *cb = vtkSimpleTimerCallback::New();
	iren->AddObserver(vtkCommand::TimerEvent, cb);
	cb->setTimerToWatch(iren->CreateRepeatingTimer(5));
	cb->initColor(sphereActor->GetProperty());

	//Define the interacting style
	vtkInteractorStyleTrackballCamera *style = vtkInteractorStyleTrackballCamera::New();
	iren->SetInteractorStyle(style);

	//Start to interact
	iren->Start();


	return 0;
}

